﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;

using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using SaleManagement.Web.App_Code;
using SaleManagement.Domains;
using SaleManagement.Services;
using DevExpress.Web.ASPxGridView;
using System.Text;
using System.Transactions;

namespace SaleManagement.Web.Pages
{
  public partial class ExportInfo : BasePage
  {
    #region Variables and properties
    private string _InnerError = string.Empty;

    private DataTable ExportDetailTable
    {
      get
      {
        if (Session["ExportDetailTable"] == null)
        {
          DataTable dt = new DataTable();
          Session["ExportDetailTable"] = dt;
        }
        return Session["ExportDetailTable"] as DataTable;
      }

      set
      {
        Session["ExportDetailTable"] = value;
      }
    }

    private int DetailId
    {
      get
      {
        if (Session["ExportDetailId"] == null)
        {
          Session["ExportDetailId"] = 0;
        }

        return Convert.ToInt32(Session["ExportDetailId"]);
      }

      set
      {


        Session["ExportDetailId"] = value;
      }
    }
    #endregion

    #region Events
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack && !IsCallback)
      {
        if (!string.IsNullOrEmpty(Request.QueryString["id"]))
        {
          hfExportId.Value = Request.QueryString["id"];
        }

        LoadCommonInfo();
        LoadExportDetailList();
      }
    }

    protected void cbxProduct_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
    {
      cbxProduct.DataSource = new ProductService().GetByGroupId(Convert.ToInt32(cbxProductGroup.Value));
      cbxProduct.DataBind();
    }

    protected void gvExportDetail_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
    {
      string[] para = e.Parameters.Split('|');
      switch (para[0])
      {
        case "DeleteDetail":
          _InnerError = DeleteExportDetail(Convert.ToInt32(para[1]));
          break;
        case "SaveDetail":
          _InnerError = SaveExportDetail();
          break;
        case "Save":
          _InnerError = Save();
          break;
        default:
          break;
      }

      LoadExportDetailList();
    }

    protected void gvExportDetail_CustomJSProperties(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewClientJSPropertiesEventArgs e)
    {
      e.Properties["cpInnerError"] = _InnerError;
    }

    protected void gvExportDetail_PageIndexChanged(object sender, EventArgs e)
    {
      LoadExportDetailList();
    }
    #endregion

    #region Methods
    private void LoadCommonInfo()
    {
      int exportId;
      if (int.TryParse(hfExportId.Value, out exportId))
      {
        #region Export
        Export export = new ExportService().GetById(exportId);
        if (export != null)
        {
          txtRefNo.Text = export.RefNo;
          deExportDate.Date = export.ExportDate;
          cbxFromRepository.Value = export.FromRepositoryId;
          cbxToRepository.Value = export.ToRepositoryId;
          txtTotalAmount.Value = export.TotalAmount;
          mmNote.Text = export.Notes;
        }
        #endregion
      }

      #region ExportDetail
      DataSet ds = new ExportDetailService().SearchByExportId(exportId);
      if (ds != null && ds.Tables.Count > 0)
      {
        ExportDetailTable = ds.Tables[0];
        ExportDetailTable.PrimaryKey = new DataColumn[] { ExportDetailTable.Columns["Id"] };
        ExportDetailTable.Columns.Add("Deleted", typeof(bool));
      }
      #endregion

      #region Combobox
      cbxProductGroup.DataSource = new ProductGroupService().GetAll();
      cbxProductGroup.DataBind();

      TList<Repository> pRepositoryList = new RepositoryService().Search(StatusList.RepositoryType.PRODUCT);
			cbxFromRepository.DataSource = pRepositoryList;
      cbxFromRepository.DataBind();

			TList<Repository> fRepositoryList = new RepositoryService().Search(StatusList.RepositoryType.FACTORY);
			fRepositoryList.AddRange(pRepositoryList.ToArray());
			cbxToRepository.DataSource = fRepositoryList;
      cbxToRepository.DataBind();
      #endregion
    }

    private void LoadExportDetailList()
    {
      gvExportDetail.DataSource = ExportDetailTable;
      gvExportDetail.FilterExpression = "Deleted <> true";
      gvExportDetail.DataBind();
    }

    private string SaveExportDetail()
    {
      #region Check parameters
      int fromRepositoryId = Convert.ToInt32(cbxFromRepository.Value);
      int productId = Convert.ToInt32(cbxProduct.Value);
      int quantity = Convert.ToInt32(txtQuantity.Text);
      foreach (DataRow row in ExportDetailTable.Select("Deleted <> 1"))
      {
        if (Convert.ToInt32(row["Id"]) <= 0 && Convert.ToInt32(row["ProductId"]) == productId)
        {
          quantity += Convert.ToInt32(row["Quantity"]);
        }
      }

      TList<StoredProduct> sProductList = new StoredProductService().GetByRepositoryIdProductId(fromRepositoryId, productId);
      if (sProductList.Count <= 0)
      {
        return "Sản phẩm này hiện chưa được nhập kho";
      }
      else if (sProductList.Count > 0 && sProductList[0].CurrentQuantity < quantity)
      {
        return "Số lượng sản phẩm yêu cầu vượt quá số lượng hiện có (" + sProductList[0].CurrentQuantity.ToString() + ").";
      }
      #endregion

      #region Save to tmp table
      try
      {
        int detailId;
        DataRow row = null;
        if (int.TryParse(hfDetailId.Value, out detailId))
        {
          row = ExportDetailTable.Rows.Find(detailId);
        }

        if (row == null)
        {
          row = ExportDetailTable.NewRow();
          row["Id"] = DetailId;
          DetailId -= 1;
          ExportDetailTable.Rows.Add(row);
        }

        row["ProductGroupId"] = cbxProductGroup.Value;
        row["ProductGroupName"] = cbxProductGroup.Text;
        row["ProductId"] = cbxProduct.Value;
        row["ProductName"] = cbxProduct.Text;
        row["Quantity"] = Convert.ToInt32(txtQuantity.Value);
        row["Deleted"] = false;

        return "SaveDetail";
      }
      catch (Exception ex)
      {
        WriteLog("ExportInfo::SaveExportDetail", ex);
        return "Có lỗi trong quá trình lưu dữ liệu";
      }
      #endregion
    }

    private string DeleteExportDetail(int id)
    {
      try
      {
        DataRow row = ExportDetailTable.Rows.Find(id);
        if (row != null)
        {
          row["Deleted"] = true;
        }

        return "DeleteDetail";
      }
      catch (Exception ex)
      {
        WriteLog("ExportInfo::DeletePurchaseExportDetai", ex);
        return "Có lỗi trong quá trình xóa dữ liệu";
      }
    }

    private string Save()
    {
      try
      {
        Export export = null;
        ExportService exportService = new ExportService();

        using (TransactionScope scope = new TransactionScope())
        {
          int exportId;
          ExportDetailService detailService = new ExportDetailService();
          ProductService productService = new ProductService();

          #region Export
          if (int.TryParse(hfExportId.Value, out exportId))
          {
            export = exportService.GetById(exportId);
          }

          if (export == null)
          {
            export = new Export();
          }

          export.ExportDate = deExportDate.Date;
          export.FromRepositoryId = Convert.ToInt32(cbxFromRepository.Value);
          export.ToRepositoryId = Convert.ToInt32(cbxToRepository.Value);
          export.TotalAmount = Convert.ToInt32(txtTotalAmount.Text);
          export.UpdatedBy = CurrentUser.Username;
          export.UpdatedDate = DateTime.Now;
          export.Notes = mmNote.Text;

          exportService.Save(export);
          #endregion

          #region Detail
          foreach (DataRow row in ExportDetailTable.Rows)
          {
            int detailId = Convert.ToInt32(row["Id"]);
            bool deleted = row["Deleted"] == DBNull.Value ? false : Convert.ToBoolean(row["Deleted"]);
            ExportDetail detail = null;
            if (detailId > 0)
            {
              detail = detailService.GetById(detailId);
            }

            if (deleted)
            {
              #region Delete
              if (detail != null)
              {
                detailService.Delete(detail);
              }
              #endregion
            }
            else
            {
              #region Save
              if (detail == null)
              {
                detail = new ExportDetail();
              }

              detail.ExportId = export.Id;
              detail.ProductId = Convert.ToInt32(row["ProductId"]);
              detail.Quantity = Convert.ToInt32(row["Quantity"]);

              detailService.Save(detail);
              row["Id"] = detail.Id;
              #endregion
            }
          }
          #endregion

          scope.Complete();
        }

        export = exportService.GetById(export.Id);
        return string.Format("Save|{0}|{1}", export.Id.ToString(), export.RefNo);
      }
      catch (Exception ex)
      {
        WriteLog("InportInfo::SaveExport", ex);
        return "Có lỗi trong quá trình lưu dữ liệu";
      }
    }
    #endregion
  }
}
